package com.example.ccj.u;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.DecimalFormat;
import java.text.NumberFormat;
import java.util.Random;

/**
 * <pre>
 *     author: blankj
 *     blog  : http://blankj.com
 *     time  : 2020/04/12
 *     desc  : utils about number
 * </pre>
 */
public final class NumberUtils {

    public static boolean equals(int s,int... s1){
        for (int i : s1) {
            if (s == i) return true;
        }
        return false;
    }

    public static int strToInt(String str){
        try{
            int i = Integer.parseInt(str);
            return i;
        }catch (Exception exception){
            ToastUtils.showShort(exception.getMessage());
            return 0;
        }
    }

    public static long strToLong(String str){
        try{
            long i = Long.parseLong(str);
            return i;
        }catch (Exception exception){
            ToastUtils.showShort(exception.getMessage());
            return 0;
        }
    }


    public static double strToDouble(String str){
        try{
            double i = Double.parseDouble(str);
            return i;
        }catch (Exception exception){
            ToastUtils.showShort(exception.getMessage());
            return 0;
        }
    }




    /**
     * 辗转相除法的递归调用求两个数的最大公约数
     * @param a 其中一个数
     * @param b 其中另一个数
     * @return 递归调用，最终返回最大公约数
     */
    public static int getBigGcb(int a, int b) {// 求两个数的最大公约数
        if (b == 0)
            return a;
        return getBigGcb(b, a % b);
    }

    /**
     * 求n个数的最大公约数
     * @param num 个数的集合
     * @param n 数据个数
     * @return 递归调用，最终返回最大公约数
     */
    public static int getBigGcb(int[] num , int n) { // 求多个数的最大公约数
        if (n == 1)
            return num[n - 1];
        return getBigGcb(num[n - 1], getBigGcb(num, n - 1));
    }

    /**
     * 辗转相除法的递归调用求两个数的最小公倍数
     * @param a 其中一个数
     * @param b 其中另一个数
     * @return 递归调用，最终返回最小公倍数
     */
    public static int getSmallMul(int a, int b) {// 求两个数的最小公倍数
        return (a * b) / getBigGcb(a, b);
    }
    /**
     * 求n个数的最小公倍数
     * @param num list n个数的集合
     * @param n 数据个数
     * @return 递归调用，最终返回最小公倍数
     */
    public static int getSmallMul(int[] num, int n) {// 求多个数的最小公倍数
        if (n == 1)
            return num[n - 1];
        return getSmallMul(num[n - 1], getSmallMul(num, n - 1));
    }


    public static int randomInt(Random random, int min, int max) {
        if ((max - min + 1) == 0) {
            return (min + max) / 2;
        }
        return random.nextInt(max) % (max - min + 1) + min;
    }

    public static int getRangeNumber(int MAX, int MIN) {
        Random rand = new Random();
        return rand.nextInt(MAX - MIN + 1) + MIN;
    }

    private static final ThreadLocal<DecimalFormat> DF_THREAD_LOCAL = new ThreadLocal<DecimalFormat>() {
        @Override
        protected DecimalFormat initialValue() {
            return (DecimalFormat) NumberFormat.getInstance();
        }
    };

    public static DecimalFormat getSafeDecimalFormat() {
        return DF_THREAD_LOCAL.get();
    }

    private NumberUtils() {
        throw new UnsupportedOperationException("u can't instantiate me...");
    }

    /**
     * Format the value.
     *
     * @param value          The value.
     * @param fractionDigits The number of digits allowed in the fraction portion of value.
     * @return the format value
     */
    public static String format(float value, int fractionDigits) {
        return format(value, false, 1, fractionDigits, true);
    }

    /**
     * Format the value.
     *
     * @param value          The value.
     * @param fractionDigits The number of digits allowed in the fraction portion of value.
     * @param isHalfUp       True to rounded towards the nearest neighbor.
     * @return the format value
     */
    public static String format(float value, int fractionDigits, boolean isHalfUp) {
        return format(value, false, 1, fractionDigits, isHalfUp);
    }

    /**
     * Format the value.
     *
     * @param value            The value.
     * @param minIntegerDigits The minimum number of digits allowed in the integer portion of value.
     * @param fractionDigits   The number of digits allowed in the fraction portion of value.
     * @param isHalfUp         True to rounded towards the nearest neighbor.
     * @return the format value
     */
    public static String format(float value, int minIntegerDigits, int fractionDigits, boolean isHalfUp) {
        return format(value, false, minIntegerDigits, fractionDigits, isHalfUp);
    }

    /**
     * Format the value.
     *
     * @param value          The value.
     * @param isGrouping     True to set grouping will be used in this format, false otherwise.
     * @param fractionDigits The number of digits allowed in the fraction portion of value.
     * @return the format value
     */
    public static String format(float value, boolean isGrouping, int fractionDigits) {
        return format(value, isGrouping, 1, fractionDigits, true);
    }

    /**
     * Format the value.
     *
     * @param value          The value.
     * @param isGrouping     True to set grouping will be used in this format, false otherwise.
     * @param fractionDigits The number of digits allowed in the fraction portion of value.
     * @param isHalfUp       True to rounded towards the nearest neighbor.
     * @return the format value
     */
    public static String format(float value, boolean isGrouping, int fractionDigits, boolean isHalfUp) {
        return format(value, isGrouping, 1, fractionDigits, isHalfUp);
    }

    /**
     * Format the value.
     *
     * @param value            The value.
     * @param isGrouping       True to set grouping will be used in this format, false otherwise.
     * @param minIntegerDigits The minimum number of digits allowed in the integer portion of value.
     * @param fractionDigits   The number of digits allowed in the fraction portion of value.
     * @param isHalfUp         True to rounded towards the nearest neighbor.
     * @return the format value
     */
    public static String format(float value, boolean isGrouping, int minIntegerDigits, int fractionDigits, boolean isHalfUp) {
        return format(float2Double(value), isGrouping, minIntegerDigits, fractionDigits, isHalfUp);
    }

    /**
     * Format the value.
     *
     * @param value          The value.
     * @param fractionDigits The number of digits allowed in the fraction portion of value.
     * @return the format value
     */
    public static String format(double value, int fractionDigits) {
        return format(value, false, 1, fractionDigits, true);
    }

    /**
     * Format the value.
     *
     * @param value          The value.
     * @param fractionDigits The number of digits allowed in the fraction portion of value.
     * @param isHalfUp       True to rounded towards the nearest neighbor.
     * @return the format value
     */
    public static String format(double value, int fractionDigits, boolean isHalfUp) {
        return format(value, false, 1, fractionDigits, isHalfUp);
    }

    /**
     * Format the value.
     *
     * @param value            The value.
     * @param minIntegerDigits The minimum number of digits allowed in the integer portion of value.
     * @param fractionDigits   The number of digits allowed in the fraction portion of value.
     * @param isHalfUp         True to rounded towards the nearest neighbor.
     * @return the format value
     */
    public static String format(double value, int minIntegerDigits, int fractionDigits, boolean isHalfUp) {
        return format(value, false, minIntegerDigits, fractionDigits, isHalfUp);
    }

    /**
     * Format the value.
     *
     * @param value          The value.
     * @param isGrouping     True to set grouping will be used in this format, false otherwise.
     * @param fractionDigits The number of digits allowed in the fraction portion of value.
     * @return the format value
     */
    public static String format(double value, boolean isGrouping, int fractionDigits) {
        return format(value, isGrouping, 1, fractionDigits, true);
    }

    /**
     * Format the value.
     *
     * @param value          The value.
     * @param isGrouping     True to set grouping will be used in this format, false otherwise.
     * @param fractionDigits The number of digits allowed in the fraction portion of value.
     * @param isHalfUp       True to rounded towards the nearest neighbor.
     * @return the format value
     */
    public static String format(double value, boolean isGrouping, int fractionDigits, boolean isHalfUp) {
        return format(value, isGrouping, 1, fractionDigits, isHalfUp);
    }

    /**
     * Format the value.
     *
     * @param value            The value.
     * @param isGrouping       True to set grouping will be used in this format, false otherwise.
     * @param minIntegerDigits The minimum number of digits allowed in the integer portion of value.
     * @param fractionDigits   The number of digits allowed in the fraction portion of value.
     * @param isHalfUp         True to rounded towards the nearest neighbor.
     * @return the format value
     */
    public static String format(double value, boolean isGrouping, int minIntegerDigits, int fractionDigits, boolean isHalfUp) {
        DecimalFormat nf = getSafeDecimalFormat();
        nf.setGroupingUsed(isGrouping);
        nf.setRoundingMode(isHalfUp ? RoundingMode.HALF_UP : RoundingMode.DOWN);
        nf.setMinimumIntegerDigits(minIntegerDigits);
        nf.setMinimumFractionDigits(fractionDigits);
        nf.setMaximumFractionDigits(fractionDigits);
        return nf.format(value);
    }

    /**
     * Float to double.
     *
     * @param value The value.
     * @return the number of double
     */
    public static double float2Double(float value) {
        return new BigDecimal(String.valueOf(value)).doubleValue();
    }
}
